package com.personal.dataanalyse.reportmanage.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.personal.core.data.DataColumn;
import com.personal.core.data.DataRow;
import com.personal.core.data.DataTable;
import com.personal.core.utils.CoreUtil;
import com.personal.dataanalyse.enums.AdditionalTypeEnum;
import com.personal.dataanalyse.enums.ModelFieldTypeEnum;
import com.personal.dataanalyse.reportmanage.base.DataAnalyseModel;
import com.personal.dataanalyse.reportmanage.base.DataChartModel;
import com.personal.dataanalyse.reportmanage.entity.ConditionInfo;
import com.personal.dataanalyse.reportmanage.entity.DataColumnReportEx;
import com.personal.dataanalyse.reportmanage.entity.DataRowReportEx;
import com.personal.dataconvert.util.ExcelHtmlUtil;

/**
 * Echart 图表模型
 * @author cuibo
 *
 */
public abstract class EChartModel extends DataChartModel
{
    /**
     * 
     */
    private static final long serialVersionUID = 6158030091798087891L;

    /** 所属模型 */
    protected DataAnalyseModel model;

    /** 图表单位 */
    protected String chartUnit;

    /** 子标题 */
    protected String chartSubName;

    /** 数据表 */
    protected DataTable table;

    /** 图表指标显示名称 */
    protected String fieldName;

    /** 图表指标名称 */
    protected String fieldData;

    /** 图表指标数据库名称 */
    protected String fieldDataSql;

    /** 颜色定义 */
    protected String colors;

    /** 横向维度 */
    protected String xGroup;
    
    /** X维度单位 */
    protected String xGroupUnit;

    /** 横向维度数据 */
    protected String xGroupData;

    /** 横向维度数据SQL */
    protected String xGroupDataSql;
    
    /** 横向维度 */
    protected String yGroup;
    
    /** X维度单位 */
    protected String yGroupUnit;

    /** 横向维度数据 */
    protected String yGroupData;

    /** 横向维度数据SQL */
    protected String yGroupDataSql;

    /** 维度合计名称，有值则增加合计 */
    protected String totalName;

    /** 是否有动画效果 */
    protected boolean animation = true;
    
    /** 是否移除不匹配的行列 */
    protected boolean removeNoMatchRowCol = false;
    
    /** 是否在图表上展示数字 */
    protected boolean showLabel = true;
    
    /** 宽度 */
    protected int width;

    public EChartModel()
    {
        super();
    }

    /**
     * table可以手动注入进来
     * 如果手动注入的table为空，则从模型中获取
     * @param table
     */
    public EChartModel(DataTable table)
    {
        super();
        this.table = table;
    }

    @Override
    public void setDataTable(DataTable table)
    {
        this.table = table;
    }

    /**
     * 
     * @param xGroups
     * @param yGroups
     * @param fieldDataNames
     * @param fieldDatas
     * @return  key x REPLACEPOINTFLAG y REPLACEPOINTFLAG 指标DataSql  value：对应的指标值
     */
    protected Map<String, String> loadHasYGroupChartData(List<Groups> xGroups, List<Groups> yGroups, String[] fieldDataNames, String[] fieldDatas)
    {
        if (table == null)
        {
            return null;
        }
        // 结果
        Map<String, String> result = new HashMap<String, String>();
        // 行列转换，为true时，指标列在行上，否则在列上
        boolean isTransRowCol = model.isTransRowCol();
        
        DataColumnReportEx hjCol = null;
        if (isTransRowCol && !CoreUtil.isEmpty(totalName))
        {
            hjCol = lookHjCol();
        }
        
        DataRowReportEx rowEx = null;
        DataColumnReportEx colEx = null;

        // 指标名称
        String quotaName = "";

        // 看指标列是在X维度上还是在Y维度上
        for (DataRow row : table.getRows())
        {
            if (!(row instanceof DataRowReportEx))
            {
                continue;
            }
            rowEx = (DataRowReportEx) row;
            // 行不显示则过滤
            if (!rowEx.isDisplay() || (removeNoMatchRowCol && !rowEx.isMatchData()))
            {
                continue;
            }

            // 图的指标是否是计算列
            boolean isCalTarget = false;
            
            sign: 
            for (DataColumn column : table.getColumns())
            {
                if (!(column instanceof DataColumnReportEx))
                {
                    continue;
                }
                colEx = (DataColumnReportEx) column;
                if (colEx.isOtherGroupCol() || !colEx.isDisplay() || (removeNoMatchRowCol && !colEx.isMatchData()))
                {
                    continue;
                }
                // 判断当前单元格是否合法
                for (Groups xGroup : xGroups)
                {
                    for (Groups yGroup : yGroups)
                    {
                        if (!checkMatchXyGroup(xGroup.value, yGroup.value, rowEx, colEx))
                        {
                            continue;
                        }
                        // 匹配上了
                        xGroup.match = true;
                        yGroup.match = true;
                        // 看指标列是在X维度上还是在Y维度上
                        if (isTransRowCol)
                        {
                            isCalTarget = ModelFieldTypeEnum.计算列.toString().equals(rowEx.getFieldType());
                            if (isCalTarget)
                            {
                                quotaName = rowEx.getFieldName();
                            } else 
                            {
                                quotaName = rowEx.getFieldDataSql();
                            }
                            quotaName = ModelFieldTypeEnum.计算列.toString().equals(rowEx.getFieldType()) ? rowEx.getFieldName() : rowEx.getFieldDataSql();
                        } else
                        {
                            isCalTarget = ModelFieldTypeEnum.计算列.toString().equals(colEx.getFieldType());
                            if (isCalTarget)
                            {
                                quotaName = colEx.getFieldName();
                            } else 
                            {
                                quotaName = colEx.getFieldDataSql();
                            }
                        }
                        
                        String key = "";
                        int index = 0;
                        for (String fieldData : isCalTarget ? fieldDataNames : fieldDatas)
                        {
                            if (fieldData.equals(quotaName))
                            {
                            	key = xGroup.value + ExcelHtmlUtil.REPLACEPOINTFLAG + yGroup.value
                                        + ExcelHtmlUtil.REPLACEPOINTFLAG + fieldDatas[index];
                            	break;
                            }
                            index ++;
                        }
                        // 没有找到对应的指标
                        if (CoreUtil.isEmpty(key))
                        {
                            continue sign;
                        }
                        // 合计需要处理
                        if (!CoreUtil.isEmpty(totalName) && totalName.equals(xGroup.value))
                        {
                            // 读取合计列的值
                            if (isTransRowCol)
                            {
                                result.put(key, CoreUtil.parseStr(CoreUtil.add(row.getItemMap().get(hjCol.getColumnName()), result.get(key))));
                                continue sign;
                            } else
                            {
                                // 仍然读取指标列的值，此时是合计行
                                for (String fieldData : isCalTarget ? fieldDataNames : fieldDatas)
                                {
                                    if (fieldData.equals(quotaName))
                                    {
                                        result.put(key, CoreUtil.parseStr(CoreUtil.add(row.getItemMap().get(colEx.getColumnName()), result.get(key))));
                                        continue sign;
                                    }
                                }
                            }
                        } else
                        {
                            for (String fieldData : isCalTarget ? fieldDataNames : fieldDatas)
                            {
                                if (fieldData.equals(quotaName))
                                {
                                    result.put(key, CoreUtil.parseStr(CoreUtil.add(row.getItemMap().get(colEx.getColumnName()), result.get(key))));
                                    continue sign;
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * @return  key x REPLACEPOINTFLAG 指标DataSql   value：对应的指标值
     * @param xGroups
     * @param fieldDataNames
     * @param fieldDatas
     */
    protected Map<String, String> loadNoYGroupChartData(List<Groups> xGroups, String[] fieldDataNames, String[] fieldDatas)
    {
        if (table == null)
        {
            return null;
        }
        // 结果
        Map<String, String> result = new HashMap<String, String>();
        // 行列转换，为true时，指标列在行上，否则在列上
        boolean isTransRowCol = model.isTransRowCol();
        
        // 需要添加合计，且是行列转model，则需要找到合计列
        DataColumnReportEx hjCol = null;
        if (isTransRowCol && CoreUtil.isEmpty(totalName))
        {
            hjCol = lookHjCol();
        }
        
        // 指标名称
        String quotaName = "";
        DataRowReportEx rowEx = null;
        DataColumnReportEx colEx = null;
        
        // 图中选择的指标是否是计算列
        boolean isCalTarget = false;

        // 看指标列是在X维度上还是在Y维度上
        for (DataRow row : table.getRows())
        {
            if (!(row instanceof DataRowReportEx))
            {
                continue;
            }
            rowEx = (DataRowReportEx) row;
            // 行不显示则过滤
            if (!rowEx.isDisplay() || (removeNoMatchRowCol && !rowEx.isMatchData()))
            {
                continue;
            }

            sign: 
            for (DataColumn column : table.getColumns())
            {
                if (!(column instanceof DataColumnReportEx))
                {
                    continue;
                }
                colEx = (DataColumnReportEx) column;
                if (colEx.isOtherGroupCol() || !colEx.isDisplay() || (removeNoMatchRowCol && !colEx.isMatchData()))
                {
                    continue;
                }
                // 判断当前单元格是否合法
                for (Groups xGroup : xGroups)
                {
                    if (!checkMatchXGroup(xGroup.value, rowEx, colEx))
                    {
                        continue;
                    }
                    // 匹配上了
                    xGroup.match = true;
                    // 看指标列是在X维度上还是在Y维度上
                    if (isTransRowCol)
                    {
                        isCalTarget = ModelFieldTypeEnum.计算列.toString().equals(rowEx.getFieldType());
                        if (isCalTarget)
                        {
                            quotaName = rowEx.getFieldName();
                        } else 
                        {
                            quotaName = rowEx.getFieldDataSql();
                        }
                        quotaName = ModelFieldTypeEnum.计算列.toString().equals(rowEx.getFieldType()) ? rowEx.getFieldName() : rowEx.getFieldDataSql();
                    } else
                    {
                        isCalTarget = ModelFieldTypeEnum.计算列.toString().equals(colEx.getFieldType());
                        if (isCalTarget)
                        {
                            quotaName = colEx.getFieldName();
                        } else 
                        {
                            quotaName = colEx.getFieldDataSql();
                        }
                    }
                    String key = "";
                    int index = 0;
                    for (String fieldData : isCalTarget ? fieldDataNames : fieldDatas)
                    {
                        if (fieldData.equals(quotaName))
                        {
                        	key = xGroup.value + ExcelHtmlUtil.REPLACEPOINTFLAG + fieldDatas[index];
                        	break;
                        }
                        index ++;
                    }
                    // 没有找到对应的指标
                    if (CoreUtil.isEmpty(key))
                    {
                        continue sign;
                    }
                    if (!CoreUtil.isEmpty(totalName) && totalName.equals(xGroup.value))
                    {
                        // 读取合计列的值
                        if (isTransRowCol)
                        {
                            result.put(key, CoreUtil.parseStr(CoreUtil.add(row.getItemMap().get(hjCol.getColumnName()), result.get(key))));
                            continue sign;
                        } else
                        {
                            // 仍然读取指标列的值，此时是合计行
                            for (String fieldData : isCalTarget ? fieldDataNames : fieldDatas)
                            {
                                if (fieldData.equals(quotaName))
                                {
                                    result.put(key, CoreUtil.parseStr(CoreUtil.add(row.getItemMap().get(colEx.getColumnName()), result.get(key))));
                                    continue sign;
                                }
                            }
                        }
                    } else
                    {
                        for (String fieldData : isCalTarget ? fieldDataNames : fieldDatas)
                        {
                            if (fieldData.equals(quotaName))
                            {
                                result.put(key, CoreUtil.parseStr(CoreUtil.add(row.getItemMap().get(colEx.getColumnName()), result.get(key))));
                                continue sign;
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
    
    /**
     * 将维度信息转成维度
     * @param groupsArr
     * @return
     */
    protected List<Groups> toGroups(String[] groupsArr)
    {
        if (CoreUtil.isEmpty(groupsArr))
        {
            return null;
        }
        List<Groups> result = new ArrayList<EChartModel.Groups>();
        for (String string : groupsArr)
        {
            result.add(new Groups(string, false));
        }
        return result;
    }
    
    /**
     * 查找合计行
     * @return
     */
    private DataColumnReportEx lookHjCol()
    {
        DataColumnReportEx colEx = null;
        for (DataColumn column : table.getColumns())
        {
            if (!(column instanceof DataColumnReportEx))
            {
                continue;
            }
            colEx = (DataColumnReportEx) column;
            if (colEx.getAdditionalType() == AdditionalTypeEnum.求和)
            {
                return colEx;
            }
        }
        return null;
    }
    
    /**
     * 检查当前模型的配置信息是否匹配当前单元格
     * @param xGroupDisplayName
     * @param yGroupDisplayName
     * @param rowEx
     * @param colEx
     * @return
     */
    private boolean checkMatchXyGroup(String xGroupDisplayName, String yGroupDisplayName, DataRowReportEx rowEx,
            DataColumnReportEx colEx)
    {
        
        // 是否是检查合计匹配
        boolean isHj = !CoreUtil.isEmpty(totalName) && totalName.equals(xGroupDisplayName);
        // cb 2017 12 10 修改为可能多个维度定义在同一个方向上
        List<ConditionInfo> conditionInfos = new ArrayList<ConditionInfo>();
        if (!CoreUtil.isEmpty(rowEx.getConditions()))
        {
            conditionInfos.addAll(rowEx.getConditions());
        }
        if (!CoreUtil.isEmpty(colEx.getConditions()))
        {
            conditionInfos.addAll(colEx.getConditions());
        }
        
        boolean xMatch = false;
        boolean yMatch = false;
        for (ConditionInfo conditionInfo : conditionInfos)
        {
            if (xGroup.equals(conditionInfo.getDimensionName()) || isHj)
            {
                if (xGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
                {
                    xMatch = true;
                }
            }
            if (yGroup.equals(conditionInfo.getDimensionName()) || isHj)
            {
                if (yGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
                {
                    yMatch = true;
                }
            }
        }
        return xMatch && yMatch;
        
//        // 图表定义的行列维度和模型定义的行列维度不一样，可能相互对应，也可能相反
//        boolean rowMatch = false;
//        boolean colMatch = false;
//        for (ConditionInfo conditionInfo : rowEx.getConditions())
//        {
//            if (xGroup.equals(conditionInfo.getDimensionName()) || isHj)
//            {
//                if (xGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
//                {
//                    rowMatch = true;
//                    break;
//                }
//            }
//            if (yGroup.equals(conditionInfo.getDimensionName()) || isHj)
//            {
//                if (yGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
//                {
//                    rowMatch = true;
//                    break;
//                }
//            }
//        }
//        for (ConditionInfo conditionInfo : colEx.getConditions())
//        {
//            if (yGroup.equals(conditionInfo.getDimensionName()) || isHj)
//            {
//                if (yGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
//                {
//                    colMatch = true;
//                    break;
//                }
//            }
//            if (xGroup.equals(conditionInfo.getDimensionName()) || isHj)
//            {
//                if (xGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
//                {
//                    colMatch = true;
//                    break;
//                }
//            }
//        }
//        return rowMatch && colMatch;
    }

    /**
     * 检查当前模型的配置信息是否匹配当前单元格
     * @param xGroupDisplayName
     * @param rowEx
     * @param colEx
     * @return
     */
    private boolean checkMatchXGroup(String xGroupDisplayName, DataRowReportEx rowEx, DataColumnReportEx colEx)
    {
        // 是否是检查合计匹配
        boolean isHj = !CoreUtil.isEmpty(totalName) && totalName.equals(xGroupDisplayName);
        
        for (ConditionInfo conditionInfo : rowEx.getConditions())
        {
            // 合计不能做此判断
            if (xGroup.equals(conditionInfo.getDimensionName()) || isHj)
            {
                if (xGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
                {
                    return true;
                }
            }
        }
        for (ConditionInfo conditionInfo : colEx.getConditions())
        {
            if (xGroup.equals(conditionInfo.getDimensionName()) || isHj)
            {
                if (xGroupDisplayName.equals(conditionInfo.getDimensionDisplayName()))
                {
                    return true;
                }
            }
        }
        return false;
    }

    public DataAnalyseModel getModel()
    {
        return model;
    }

    public void setModel(DataAnalyseModel model)
    {
        this.model = model;
    }

    public DataTable getTable()
    {
        return table;
    }

    public void setTable(DataTable table)
    {
        this.table = table;
    }

    public String getFieldName()
    {
        return fieldName;
    }

    public void setFieldName(String fieldName)
    {
        this.fieldName = fieldName;
    }

    public String getFieldData()
    {
        return fieldData;
    }

    public void setFieldData(String fieldData)
    {
        this.fieldData = fieldData;
    }

    public String getFieldDataSql()
    {
        return fieldDataSql;
    }

    public void setFieldDataSql(String fieldDataSql)
    {
        this.fieldDataSql = fieldDataSql;
    }

    public String getColors()
    {
        return colors;
    }

    public void setColors(String colors)
    {
        this.colors = colors;
    }

    public String getxGroup()
    {
        return xGroup;
    }

    public void setxGroup(String xGroup)
    {
        this.xGroup = xGroup;
    }

    public String getxGroupData()
    {
        return xGroupData;
    }

    public void setxGroupData(String xGroupData)
    {
        this.xGroupData = xGroupData;
    }

    public String getxGroupDataSql()
    {
        return xGroupDataSql;
    }

    public void setxGroupDataSql(String xGroupDataSql)
    {
        this.xGroupDataSql = xGroupDataSql;
    }

    public String getyGroup()
    {
        return yGroup;
    }

    public void setyGroup(String yGroup)
    {
        this.yGroup = yGroup;
    }

    public String getyGroupData()
    {
        return yGroupData;
    }

    public void setyGroupData(String yGroupData)
    {
        this.yGroupData = yGroupData;
    }

    public String getyGroupDataSql()
    {
        return yGroupDataSql;
    }

    public void setyGroupDataSql(String yGroupDataSql)
    {
        this.yGroupDataSql = yGroupDataSql;
    }

    public String getChartUnit()
    {
        return chartUnit;
    }

    public String getxGroupUnit()
    {
        return xGroupUnit;
    }

    public void setxGroupUnit(String xGroupUnit)
    {
        this.xGroupUnit = xGroupUnit;
    }

    public String getyGroupUnit()
    {
        return yGroupUnit;
    }

    public void setyGroupUnit(String yGroupUnit)
    {
        this.yGroupUnit = yGroupUnit;
    }

    public void setChartUnit(String chartUnit)
    {
        this.chartUnit = chartUnit;
    }

    public String getChartSubName()
    {
        return chartSubName;
    }

    public void setChartSubName(String chartSubName)
    {
        this.chartSubName = chartSubName;
    }

    public boolean isAnimation()
    {
        return animation;
    }

    public void setAnimation(boolean animation)
    {
        this.animation = animation;
    }

    public String getTotalName()
    {
        return totalName;
    }

    public void setTotalName(String totalName)
    {
        this.totalName = totalName;
    }

    public boolean isRemoveNoMatchRowCol()
    {
        return removeNoMatchRowCol;
    }

    public void setRemoveNoMatchRowCol(boolean removeNoMatchRowCol)
    {
        this.removeNoMatchRowCol = removeNoMatchRowCol;
    }
    
    public boolean isShowLabel()
    {
        return showLabel;
    }

    public void setShowLabel(boolean showLabel)
    {
        this.showLabel = showLabel;
    }

    public int getWidth()
    {
        return width;
    }

    public void setWidth(int width)
    {
        this.width = width;
    }



    /**
     * 维度信息
     * @author cuibo
     *
     */
    protected static class Groups
    {
        protected String value;
        protected boolean match;
        
        public Groups()
        {
            super();
        }

        public Groups(String value, boolean match)
        {
            super();
            this.value = value;
            this.match = match;
        }
        
    }
    
}